package com.legrand.route.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Maps;
import com.legrand.route.constant.ThirdLoginType;
import com.legrand.route.constant.ZuulHelp;
import com.legrand.route.service.TokenService;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.Map;

/**
 * @author xiah
 * 2018-06-27 10:11:18
 * 用户认证过滤器
 */
public class UserSecurityFilter extends ZuulFilter {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private ObjectMapper mapper;

    @Autowired
    private TokenService tokenService;

    @Override
    public int filterOrder() {
        return 1;
    }

    @Override
    public String filterType() {
        return "pre";
    }

    /**
     * @author xiah
     * 2018-06-27 10:20:11
     * 判断是否需要过滤
     */
    @Override
    public boolean shouldFilter() {
        boolean shouldFilter = false;
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String sa=request.getRequestURI();
        if (request.getRequestURI().contains(ZuulHelp.FILTER_URL)) {
            shouldFilter = true;
        }
        return shouldFilter;
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        final String authHeader = request.getHeader("Authorization");
        /**使用accessToken方式认证*/
        if (authHeader != null && authHeader.startsWith(ZuulHelp.BEARER) && authHeader.length() > 7 && request.getHeader("type") != null) {
            final String accessToken = authHeader.substring(7);
            final String jwtToken = tokenService.accessTokenCheck(accessToken, request.getHeader("type"));
            ctx.addZuulRequestHeader("Authorization", "Bearer " + jwtToken);
                return null;
        } else if (authHeader.startsWith(ZuulHelp.BASIC) && authHeader.length() > 6) {
            final String openId = authHeader.substring(6);
            final String openIdType = request.getHeader("openIdType");
            Boolean checkEncryptionType = ThirdLoginType.checkThirdLoginType(openIdType);
            if (checkEncryptionType) {
                /**使用第三方登录方式鉴权*/
                Boolean check = tokenService.otherSecurityCheck(openId, openIdType);
                if (!check) {
                    logger.warn("openid: {},openidType: {} user has been deleted", openId, openIdType);
                    this.userHasBeenDeteled();
                } else {
                    /**需将用户信息加入security*/
                    return null;
                }
            } else {
                logger.warn("openid: {},openidType: {} Illegal Request", openId, openIdType);
                this.illegalRequest();
            }
        }
        return null;
    }

    private void unauthorized() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletResponse resp = ctx.getResponse();
        resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        resp.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        Map<String, Object> resultMap = Maps.newHashMap();
        try {
            resultMap.put("code", "0040001");
            resultMap.put("devMessage", "UNAUTHORIZED");
            resultMap.put("usrMessage", "认证失败,请重新获取Token");
            resultMap.put("timestamp", new Date());
            PrintWriter writer = resp.getWriter();
            mapper.writeValue(writer, resultMap);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        ctx.setSendZuulResponse(false);
    }

    private void userHasBeenDeteled() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletResponse resp = ctx.getResponse();
        resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        resp.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        Map<String, Object> resultMap = Maps.newHashMap();
        try {
            resultMap.put("code", "0040001");
            resultMap.put("devMessage", "UNAUTHORIZED");
            resultMap.put("usrMessage", "此用户已经删除");
            resultMap.put("timestamp", new Date());
            PrintWriter writer = resp.getWriter();
            mapper.writeValue(writer, resultMap);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        ctx.setSendZuulResponse(false);
    }

    private void illegalRequest() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletResponse resp = ctx.getResponse();
        resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        resp.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        Map<String, Object> resultMap = Maps.newHashMap();
        try {
            resultMap.put("code", "0040001");
            resultMap.put("devMessage", "UNAUTHORIZED");
            resultMap.put("usrMessage", "非法请求");
            resultMap.put("timestamp", new Date());
            PrintWriter writer = resp.getWriter();
            mapper.writeValue(writer, resultMap);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        ctx.setSendZuulResponse(false);
    }

}
